#include<iostream>
using namespace std;
#include"Thread.hpp"
#include<memory>
#include<string>
#include<unistd.h>
#include<string>
#include<vector>


// void* thread_run(void* args){
//     string work_type = static_cast<const char*>(args);
//     int cnt = 10;
//     while(cnt--){
//         cout<<"我是一个新线程，我正在做："<<work_type<<endl;
//         sleep(1);
//     }
//     return nullptr;
// }



//pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;//创建一个锁

class ThreadDate{
public:
    ThreadDate(const string& threadname, pthread_mutex_t* mutex_t):_threadname(threadname),_mutex_t(mutex_t){

    }
    ~ThreadDate(){

    }
public:
    string _threadname;
    pthread_mutex_t* _mutex_t;
};


int ticket = 10000;
void* get_ticket(void* args){
   // string username = static_cast<const char*>(args);
    ThreadDate* td = static_cast<ThreadDate*>(args);
    while(true){
        //pthread_mutex_lock(&lock);//加锁
        //这中间的就是所谓的临界区
        pthread_mutex_lock(td->_mutex_t);//加锁
        if(ticket > 0){
            usleep(123);
            cout<<td->_threadname<<"正在抢票："<<ticket<<endl;
            ticket--;
            //pthread_mutex_unlock(&lock);//解锁
            pthread_mutex_unlock(td->_mutex_t);
        }else{
            //pthread_mutex_unlock(&lock);
            pthread_mutex_unlock(td->_mutex_t);

            break;
        }
        //usleep(1000);
    }
    return nullptr;
}


int main(){
    // unique_ptr<Thread> t1(new Thread(get_ticket,(void*)"user1",1));
    // unique_ptr<Thread> t2(new Thread(get_ticket,(void*)"user2",2));
    // unique_ptr<Thread> t3(new Thread(get_ticket,(void*)"user3",3));
    // unique_ptr<Thread> t4(new Thread(get_ticket,(void*)"user4",4));


    //在主线程创建锁,但是要把锁传给新线程
    pthread_mutex_t lock;
    pthread_mutex_init(&lock,nullptr);
    vector<pthread_t> tids(4);//创建4个新线程

    for(int i = 1;i<=4;i++){
        char buffer[128];
        snprintf(buffer,sizeof buffer,"thread:%d",i);
        ThreadDate* td = new ThreadDate(buffer,&lock);
        pthread_create(&tids[i],nullptr,get_ticket,td);//最后一个参数直接传结构体,相当于把线程的名称和锁一起传给了执行流
    }

    //线程等待
    for(auto e:tids){
        pthread_join(e,nullptr);
    }


    //pthread_t t1,t2,t3,t4;
    //我们要把创建的锁传入到新进程的执行流。
    // pthread_create(&t1,nullptr,get_ticket,(void*)"thread 1");
    // pthread_create(&t2,nullptr,get_ticket,(void*)"thread 2");
    // pthread_create(&t3,nullptr,get_ticket,(void*)"thread 3");
    // pthread_create(&t4,nullptr,get_ticket,(void*)"thread 4");

    // pthread_join(t1,nullptr);
    // pthread_join(t2,nullptr);
    // pthread_join(t3,nullptr);
    // pthread_join(t4,nullptr);



    //销毁锁
    pthread_mutex_destroy(&lock);





    // t1->join();
    // t2->join();
    // t3->join();
    // t4->join();



    return 0;
}